#include "gametimer.h"

namespace util {

bool GameTimer::sdl_quit = false;

GameTimer::GameTimer(int fps, int maxfskip, bool enable_events) :
	roundtime(1000/fps),
	nextround(SDL_GetTicks()),
	maxfskip(maxfskip),
	fskip(-1),
	enable_events(enable_events)
{
}

void GameTimer::resume() {
	nextround = SDL_GetTicks();
	fskip = -1;
}

void GameTimer::wait() {
	uint32 ctime = SDL_GetTicks();
	if(ctime < nextround) {
		// Sleep until action needed
		SDL_Delay(nextround-ctime);
	}
	else if(ctime > nextround + 1000) { 
		// Reset timer; suspect a lag spike too long to be corrected
		resume();
	}
}

bool GameTimer::logic() {
	// Handle system events
	events();

	// No running game after window close
	if(sdl_quit) return false;

	if(SDL_GetTicks() < nextround) {
		// Not yet time for logic
		fskip = -1;
		return false;
	}

	if(fskip >= maxfskip) {
		// Max number of frames skipped; draw
		fskip = -1;
		return false;
	}

	nextround += roundtime;
	++fskip;
	return true;
}

void GameTimer::events() {
	std::vector<SDL_Event> game_events;
	
	// Handle system events first
	SDL_Event e;
	while(SDL_PollEvent(&e)) {
		switch(e.type) {
			case SDL_QUIT:
				sdl_quit = true;
				break;
			default:
				if(enable_events) game_events.push_back(e);
				break;
		}
	}

	// Push non-system events back
	if(enable_events) {
		foreach(SDL_Event e, game_events) {
			SDL_PushEvent(&e);
		}
	}
}

}